import org.jdom.JDOMException;

import java.io.*;
import java.util.*;


public class Program {
    static List<String> getQueries(String file) throws IOException, UnsupportedEncodingException {
        ArrayList<String> queries = new ArrayList<String>();

        HashSet<String> done = new HashSet<String>();

        String strLine;

        FileInputStream doneStream = new FileInputStream(file + ".done");
        BufferedReader doneReader = new BufferedReader(new InputStreamReader(doneStream, "UTF-8"));
        while ((strLine = doneReader.readLine()) != null)   {
            done.add(strLine);
        }
        doneStream.close();

        FileInputStream fstream = new FileInputStream(file);
        BufferedReader br = new BufferedReader(new InputStreamReader(fstream, "UTF-8"));
        while ((strLine = br.readLine()) != null)   {
            if (!done.contains(strLine)) queries.add(strLine);
        }
        fstream.close();

        return queries;
    }

    static BookTrie getTrie(String booksXml) throws JDOMException, IOException {
        List<Book> books = Book.load(booksXml);
        DictionaryTrie trie = new DictionaryTrie();
        for(Book book : books) {

            String[] author = book.Author.toLowerCase().split("[^a-zа-я0-9]+");

            String article = book.getPrettyArticleName();

            List<String> titles = new ArrayList<String>();
            if (!book.Title.isEmpty()) titles.add(book.Title);
            if (!book.OriginalTitle.isEmpty()) titles.add(book.OriginalTitle);
            if (!article.isEmpty()) titles.add(article);

            BookTrieInfo info = null;
            for(String title : titles) {
                String[] prefix = title.toLowerCase().split("[^a-zа-я0-9]+");
                if (info==null)
                    info = trie.add(author,prefix);
                else
                    trie.add(prefix, info);
            }
        }
        return trie;
    }

    public static void main(String[] args) throws Exception, JDOMException {
        String booksArg = null;
        String searchCacheArg = null;
        String htmlCacheArg = null;
        String htmlDirArg = null;
        String queriesArgs = null;
        String outputArgs = null;
        boolean isCache = false;
        boolean isCacheOnly = false;
        boolean explain = false;

        for (int i=0;i<args.length;i++){
            if (args[i].equals("--books")) {
                booksArg = args[++i];
            } else if (args[i].equals("--searchCache")) {
                searchCacheArg = args[++i];
            } else if (args[i].equals("--htmlCache")) {
                htmlCacheArg = args[++i];
            } else if (args[i].equals("--queries")) {
                queriesArgs = args[++i];
            } else if (args[i].equals("--output")) {
                outputArgs = args[++i];
            } else if (args[i].equals("--htmlDir")) {
                htmlDirArg = args[++i];
            } else if (args[i].equals("--cache")) {
                isCache = true;
            } else if (args[i].equals("--cacheOnly")) {
                isCache = true;
                isCacheOnly = true;
            } else if (args[i].equals("--explain")) {
                explain = true;
            }
        }

        BookTrie trie = getTrie(booksArg);

        SearchEngine engine = null;

        if (isCache) {
            File searchCache = new File(searchCacheArg);
            File docCache = new File(htmlCacheArg);
            if (!searchCache.exists()) searchCache.createNewFile();
            if (!docCache.exists()) docCache.createNewFile();

            CachingYaSearchEngine cachingEngine = new CachingYaSearchEngine(
                searchCache.getPath(),
                docCache.getPath(),
                htmlDirArg
            );

            cachingEngine.setCacheOnly(isCacheOnly);

            engine = cachingEngine;
        } else engine = new YaSearchEngine();

        File doneQueries = new File(queriesArgs + ".done");
        File filteredQueries = new File(outputArgs);
        if(!doneQueries.exists()) doneQueries.createNewFile();
        if(!filteredQueries.exists()) filteredQueries.createNewFile();

        List<String> queries = getQueries(queriesArgs);

        FileOutputStream doneQueriesStream = new FileOutputStream(doneQueries.getPath(), true);
        OutputStreamWriter doneQueriesWriter = new OutputStreamWriter(doneQueriesStream,"UTF-8");

        FileOutputStream bookQueriesStream = new FileOutputStream(filteredQueries.getPath(), true);
        OutputStreamWriter bookQueriesWriter = new OutputStreamWriter(bookQueriesStream,"UTF-8");

        Classifier classifier = new DoubleBookClassifier();
        classifier.setTrie(trie);
        classifier.setSearchEngine(engine);

        for(String query : queries){
            ClassifierDecisionInfo info = classifier.makeDecision(query);
            if (info.isBookRelatedQuery){
                if (explain) {
                    System.out.println(query);
                    for(String comment : info.comments) {
                        System.out.println("\t" + comment);
                    }
                }

                bookQueriesWriter.write(query + "\n");
                bookQueriesWriter.flush();
            }

            doneQueriesWriter.write(query + "\n");
            doneQueriesWriter.flush();
        }

        bookQueriesStream.close();
        doneQueriesStream.close();

        if (isCache) {
            ((CachingYaSearchEngine)engine).dispose();
        }
    }
}
